import math
import noise, util
import datetime
import random

def getCoordinatesBetweenXandYinMiles(gpsCoords, speed, interval, startTime):
    return getCoordinatesBetweenXandY(gpsCoords, speed / 1.6, interval, startTime)

"""
 this function returns the samples for all GPS coordinates between two points
 gpsCoords is a list of GPS coordinates of the road
 length is the length of the road in km
 speed is the speed of the car in km/h
 interval is the sampling interval
 
 output:
 ( list of routes, list of noisy routes)
 the routes are in the format: lat, long, horz error, timestamp, speed, speed error
 """
def getCoordinatesBetweenXandY(gpsCoords, speed, interval, startTime):
    currTime = startTime
    delta    = datetime.timedelta(seconds = interval)
    rtn = []
    for numEdge in range(len(gpsCoords) - 1):
        newSpeed   = abs(random.gauss(speed, 5))  # MAKE SPEED SOMEWHAT DEPENDENT ON LENGTH
        start      = gpsCoords[numEdge]
        end        = gpsCoords[numEdge + 1]
        numSamples = numberOfSamplesNeeded(start, end, newSpeed, interval)
        if numSamples == 0:
            numSamples = 1
        frac       = 1.0 / (numSamples + 1)
        for sampleNum in range(numSamples):
            # each line consists of: lat, long, horz accuracy, time, speed, speedAcc
            rtn.append(linearInterp(start, end, sampleNum * frac) + [0, currTime.strftime("%Y-%m-%d %H:%M:%S"),newSpeed,0])
            currTime += delta
    rtn.append(list(end) + [0, currTime.strftime("%Y-%m-%d %H:%M:%S"),newSpeed,0])
    return (rtn, noise.run1(rtn, interval, speed))

"""
 x and y are tuples of gps coordinates
 frac is a number between 0 and 1 indicating how much in between x and y
 
 output: [lat, long]
 """
def linearInterp(x, y, frac):
    newX = x[0] + frac * (y[0] - x[0])
    newY = x[1] + frac * (y[1] - x[1])
    return [newX, newY]

"""
 start and end are lists which hold the coordinates lat,long
 speed in km/hour which needs to be converted to km/minute
 number of seconds between each sample
 we add 0.5 to the end to have the number rounded to the nearest int
 """
def numberOfSamplesNeeded(start, end, speed, interval):
    totalDist     = util.getApproxDistanceKM(start, end)
    period        = 1.0 / (60.0 / interval)
    distPerSample = period * speed / 60.0
    return int(float(totalDist) / distPerSample + 0.5)


"""
OLD TEST FUNCTION

speed = 10
interval = 10

coord = util.parseGeoText(" MULTILINESTRING((-118.507186 32.9309879991387,-118.506588 32.9312169991387,-118.506289 32.9312399991387,-118.505828 32.9308269991386,-118.505177 32.9299789991387,-118.504932 32.9299559991387,-118.504525 32.9301849991387,-118.503981 32.9303449991386,-118.503519 32.9303449991386,-118.501456 32.9295419991387,-118.500911 32.9289339991387))")
print "length of original", str(len(coord))
a = getCoordinatesBetweenXandY(coord, speed, interval)
print "length of sampled", str(len(a))
noisyA = noise.run1(a, interval)
print "length of sampled", str(len(noisyA))

f = open("originalGPS.txt", 'w')
for lat,long in coord:
    f.write(str(lat))
    f.write(",")
    f.write(str(long))
    f.write("\n")
f.close()

f = open("sampledGPS.txt", 'w')
for lat,long in a:
    f.write(str(lat))
    f.write(",")
    f.write(str(long))
    f.write("\n")
f.close()

f = open("noisySampledGPS.txt", 'w')
for lat,long in noisyA:
    f.write(str(lat))
    f.write(",")
    f.write(str(long))
    f.write("\n")
f.close()
"""
